package com.sc.admin.base.service.impl;

import com.sc.admin.base.mapper.SystemMapper;
import com.sc.admin.base.service.ISystemService;
import com.sc.common.response.Response;
import com.sc.core.configtion.ScConfiguration;
import com.sc.core.make.MasterMake;
import com.sc.core.make.dto.MakeInfoDTO;
import com.sc.core.make.vo.TableColumn;
import com.sc.core.make.vo.TableInfo;
import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;

import java.io.File;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Primary
@Service
@AllArgsConstructor
@Log4j2
public class ISystemServiceImpl implements ISystemService {

    private final SystemMapper systemMapper;
    private final ScConfiguration scConfiguration;
    private final MasterMake masterMake;

    @Override
    public List<String> makeCurd(MakeInfoDTO makeInfo) {
        List<String> message = masterMake.make(makeInfo);
        log.info("scConfiguration111: {}", scConfiguration);
        return message;
    }

    @Override
    public List<TableInfo> getTableList() {
        return systemMapper.getTableList();
    }

    @Override
    public List<TableColumn> getTableColumn(String tableName) {
        return systemMapper.getTableColumn(tableName);
    }

    @Override
    public List<String> getAdminPackageList() {
        List<String> list = Arrays.stream(System.getProperty("java.class.path").split(";"))
                .filter(s -> s.contains(File.separator + "target") && !s.endsWith(".jar"))
                .toList();
        List<String> packageNames = new ArrayList<>();
        list.forEach(s -> {
            String dir = s.replace("target" + File.separator + "classes", "");
            dir = String.join(File.separator, new String[]{dir, "src", "main", "java"});

            File[] files = new File(dir).listFiles(File::isDirectory);
            if (files != null) {
                for (File file : files) {
                    packageNames.addAll(getPackageNames(file));
                }
            }
        });

        return packageNames.stream()
                .filter(s -> s.contains("admin") && s.length() - s.replace(".", "").length() > 1)
                .collect(Collectors.toList());
    }

    private List<String> getPackageNames(File file) {
        List<String> packages = new ArrayList<>();
        packages.add(file.getName());
        File[] files = file.listFiles(File::isDirectory);
        if (files == null) {
            return packages;
        }

        Arrays.stream(files).toList().forEach(children -> {
            List<String> childrenFiles = getPackageNames(children);
            childrenFiles.forEach(childrenFile -> {
                packages.add(file.getName() + "." + childrenFile);
            });
        });

        return packages;
    }

    @Override
    public List<String> getAdminModuleList() {
        List<String> list = Arrays.stream(System.getProperty("java.class.path").split(";"))
                .filter(s -> s.contains(File.separator + "target") && !s.endsWith(".jar"))
                .toList();

        List<String> adminModule = list.stream().filter(s -> s.contains("admin-")).toList();
        return  adminModule.stream().map(s -> {
            Matcher matcher = Pattern.compile("admin-(\\w+)").matcher(s);
            return matcher.find() ? matcher.group(1) : "";
        }).toList();
    }
}
